package com.pixel.game.Utils;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.pixel.game.entity.Unit;

import java.util.ArrayList;
import java.util.List;

public class PositionUtils {

    /**
     * 计算中心点
     *
     * @param units units
     */
    public static Vector2 calculateCenter(List<Unit> units) {
        float totalX = 0;
        float totalY = 0;
        for (Unit unit : units) {
            totalX += unit.getPosition().x;
            totalY += unit.getPosition().y;
        }
        return new Vector2(totalX / units.size(), totalY / units.size());
    }

    /**
     * 生成随机坐标
     *
     * @param existingUnits 已存在的单位坐标
     * @param unitSize      unit大小
     */
    public static Vector2 findRandomPosition(List<Vector2> existingUnits, float unitSize) {
        float screenWidth = getScreenWidth();
        float screenHeight = getScreenHeight();
        boolean positionFound = false;
        Vector2 newPosition = new Vector2();

        while (!positionFound) {
            newPosition.set(MathUtils.random(0, screenWidth), MathUtils.random(0, screenHeight));
            positionFound = true;

            for (Vector2 existingUnit : existingUnits) {
                if (newPosition.dst(existingUnit) < unitSize) {
                    positionFound = false;
                    break;
                }
            }
        }
        return newPosition;
    }

    /**
     * 判定禁止区域
     *
     * @param position
     * @param centerX
     * @param centerY
     * @param width
     * @param height
     * @return
     */
    public static boolean isInRestrictedArea(Vector2 position, float centerX, float centerY, float width, float height) {
        float halfWidth = width / 2;
        float halfHeight = height / 2;

        return position.x > (centerX - halfWidth) && position.x < (centerX + halfWidth) &&
            position.y > (centerY - halfHeight) && position.y < (centerY + halfHeight);
    }

    public static Vector2 screenToWorld(int screenX, int screenY) {
        return new Vector2(screenX, Gdx.graphics.getHeight() - screenY);
    }

    /**
     * 更新unit坐标
     *
     * @param units
     * @param targets
     * @param speed
     * @param deltaTime
     */
    public static void updateUnitPositions(List<Unit> units, List<Vector2> targets, float speed, float deltaTime) {
        for (int i = 0; i < units.size(); i++) {
            Vector2 unit = units.get(i).getPosition();
            Vector2 target = targets.get(i);
            Vector2 direction = target.cpy().sub(unit).nor();
            float distance = speed * deltaTime;
            if (unit.dst(target) > distance) {
                unit.add(direction.scl(distance));
            } else {
                unit.set(target);
            }
        }
    }

    /**
     * 重组队形
     *
     * @param units
     * @param targets
     * @param center
     * @param unitSize
     */
    public static void arrangeUnitsInCompactFormation(List<Unit> units, List<Vector2> targets,
                                                      Vector2 center, float unitSize) {
        int numUnits = units.size();
        int unitsPerRow = (int) Math.ceil(Math.sqrt(numUnits));
        float spacing = unitSize * 2.5f;

        targets.clear();

        for (int i = 0; i < numUnits; i++) {
            int row = i / unitsPerRow;
            int col = i % unitsPerRow;
            float offsetX = (col - unitsPerRow / 2) * spacing + spacing / 2;
            float offsetY = (row - numUnits / unitsPerRow / 2) * spacing + spacing / 2;

            Vector2 offset = new Vector2(offsetX, offsetY);
            targets.add(new Vector2(center).add(offset));
        }
    }

    public static Unit findNearestTargetUnit(Unit unit, List<? extends Unit> targetUnits) {
        Unit nearest = null;
        float minDistance = Float.MAX_VALUE;

        for (Unit target : targetUnits) {
            float distance = unit.getPosition().dst(target.getPosition());
            if (distance < minDistance) {
                minDistance = distance;
                nearest = target;
            }
        }

        return nearest;
    }

    public static float getScreenWidth() {
        return Gdx.graphics.getWidth();
    }

    public static float getScreenHeight() {
        return Gdx.graphics.getHeight();
    }

    public static float getUnitSize() {
        return 5.0f;
    }

    public static List<Vector2> getUnitPositions(List<? extends Unit> units) {
        List<Vector2> positions = new ArrayList<>();
        for (Unit unit : units) {
            positions.add(unit.getPosition());
        }
        return positions;
    }
}
